<script setup lang="ts">
import { ref, provide, inject, reactive, onMounted, onUnmounted } from 'vue'
import { useCounterStore } from './../stores/counter'
import { useRouter } from 'vue-router'
import { NGrid, NGridItem, NButton, NIcon, NFlex, NText, NBadge, NModal, useDialog, NInput } from 'naive-ui';
import SvgIcon from '@/components/SvgIcon.vue'
import { APP_DEL, APP_GROUP_UPD } from "@/service/apis/from";
import { createDiscreteApi } from "naive-ui";
const { message } = createDiscreteApi(["message"])
const dialog = useDialog()
import { storeToRefs } from 'pinia';

import { sseService } from "../assets/utils/sse";
import type { SSEChatParams } from "../assets/utils/sse";
import { sseUrl } from "@/service/sseUrl";
import Papa from "papaparse";

/**
 * 状态管理
 */
const counterStore = useCounterStore()

// const {increment} = counterStore
// increment()


// console.log('pinia在我的应用', counterStore.count)
/**
 * end
 */
/**
 * 这是个注入的例子
 */
const wyy = inject('wyy')
console.log(wyy)

/**
 * 我的应用，固定平台应用配置
 */
const router = useRouter()
// 配置全部的平台默认应用
interface appNameItem {
    id: string;
    图标: string
    路由: string
    名称: string
    固定: boolean
    缩写: string
    类型: string
}
const defaultApps = ref<any[]>([
    { 图标: "wodeshujuji", 路由: "dataset", 名称: "我的数据包", 固定: true },
    { 图标: "wodericheng1", 路由: "日程", 名称: "我的日程", 固定: true },
    { 图标: "Word-Color", 路由: "word", 名称: "Word文稿", 固定: true },
    { 图标: "excel1", 路由: "excel", 名称: "Excel表格", 固定: true },
    { 图标: "shezhi4", 路由: "setting", 名称: "设置", 固定: true },
    { 图标: "shipinhuiyi", 路由: "meeting", 名称: "可视电话", 固定: true },
    { 图标: "xiaochengxu", 路由: "wxxc", 名称: "AI自建小程序", 固定: false },
    { 图标: "zhinengAI", 路由: "aiapp", 名称: "AI引导应用创建", 固定: false },
    { 图标: "wodeyingyong3", 路由: "3d", 名称: "3D工厂", 固定: true },
    // { 图标: "excel1", 路由: "echarts-excel", 名称: "echarts-excel", 固定: true },
    // { 图标: "excel1", 路由: "echarts-excel-3d", 名称: "echarts-excel-3d", 固定: true },
    // { 图标: "excel1", 路由: "echarts-3d", 名称: "echarts-3d", 固定: true },
    // { 图标: "excel1", 路由: "echarts-word", 名称: "echarts-word", 固定: true },
])
/**
 * 点击事件
 * @param value 
 * @returns 
 */
const handleClick = (value: appNameItem) => {
    console.log('底部应用：', value)
    if (value.固定) {
        router.push(value.路由)
        console.log('固定应用的点击事件', value);

    } else {
        console.log('动态应用的点击事件', value);
        // counterStore.increment({ 图标: "excel", 路由: "excel", 名称: "excel" })
        counterStore.pushDynamicApp({ 图标: value.图标, 路由: value.路由, 名称: value.名称, 缩写: value.缩写, 类型: value.类型, })
        // let val = JSON.stringify(value)
        // let str = encodeURIComponent(val)
        router.push({
            name: value.路由,
            params: {
                data: value.缩写
            }
        })
    }
    showFolder(value)
}
/**
 * 我的应用end
 */
/**
 * 动态应用添加
 */
const dynamicApps = ref<any[]>([])

/**
 * end
 */

/**
 * 右键菜单
 */
const none = (event: any) => {
    console.log(event)
}
/**
 * end
 */

onMounted(() => {
    sseServiceOpen()
})

onUnmounted(() => {
    sseService.disconnect()
})

//see 链接
function sseServiceOpen() {
    console.log(sseService);

    const onopen = () => {
        console.log("消息菜单建立sse连接成功", sseUrl.meun)
    }
    // 建立连接
    let sseChatParams: SSEChatParams = {
        onopen,
        url: sseUrl.meun,
        onmessage: (event: MessageEvent) => {
            // 收到消息
            let fst = event.data.replace(/\\n/g, "\n")
            const meun = Papa.parse(fst, { header: true, delimiter: ";", newline: "\n" })
            console.log('收到消息菜单：', meun);
            let newList = meun.data.map((item: any) => {
                console.log('应用',item)
                // return { id: item.id, 名称: item.应用名称, 缩写: item.缩写, 图标: item.图标名, 类型: item.类型, 路由: item.类型 == 'word' ? 'showFiles' : 'showFiles', 固定: false }
                return { id: item.id, 名称: item.应用名称, 缩写: item.缩写, 图标: item.图标名, 类型: item.类型, 路由: 'main', 固定: false, 子应用: item.子应用 }
            })

            const mergedArray = [...dynamicApps.value, ...newList].reduce(
                (theArray, item) => {
                    const index = theArray.findIndex((arrItem: any) => arrItem['id'] === item['id']);
                    console.log(index);
                    if (index === -1) { // 已经规约到的数组中，找到了新元素，说明新元素是重复元素，则不添加
                        theArray.push(item);
                    } else {   
                        theArray[index] = item; // 更新元素
                    }
                    return theArray;
                }, []);

            dynamicApps.value = renderAppGroup(mergedArray)
        },
        finallyHandler: () => {
            console.log("finallyHandler操作")
        }
    };
    sseService.connect(sseChatParams)
}
const renderAppGroup = (list: any[]) => {
    const groupList: any[] = list.filter((item:any) => item.类型 === 'group')
    const appList: any[] = list.filter((item:any) => item.类型 !== 'group')
    let hideAppIds: any[] = []
    groupList.forEach((item: any) => {
        const groupAppIdList= JSON.parse(item.子应用)
        hideAppIds = [...new Set([...hideAppIds, ...groupAppIdList])] // 合并 去重（其实不去重也不影响后续逻辑），找到需要隐藏的动态应用
        
        // 设置这个Group的图标组
        item.图标组 = groupAppIdList.map((id: string) => { 
            return appList.find((app: any) => app.id === id)?.图标
        }).slice(0, 4) // 截取前4个图标

        item.路由 = undefined // 路由设置为undefined，双击时不会跳转
        item.type = 'group' // 类型设置为group，这样的话类型和type都是Group，前端会根据type来响应
        item.appIds = groupAppIdList // 设置group应用id列表
        console.log('组中应用', item, groupAppIdList, appList)
    })
    
 return list.map((item: any) => {
    // 对于已经在组中的动态应用，设置一个隐藏hide属性
    if (hideAppIds.includes(item.id)) {
        return {
            ...item,
            hide: true
        }
    } else {
        return item
    }
 })

}

let isLongPressing = false;
let longPressTimer: any
let showCloseButton = ref(false)
/**
 * 监听鼠标点击和抬起实现长按功能
 */
const handleMouseDown = (item: appNameItem) => {
    console.log('鼠标按下')
    // 阻止默认行为，比如选择文本  
    isLongPressing = false;
    // 设置长按定时器  
    longPressTimer = setTimeout(() => {
        if (isOnDrag) {
            return
        }
        isLongPressing = true;
        handleLongPress(item);
    }, 1200);
    setTimeout(() => {
        if (isOnDrag) {
            clearTimeout(longPressTimer);
        }
    }, 500);
}
const handleMouseUp = () => {
    console.log('鼠标抬起')
    // 清除长按定时器  
    clearTimeout(longPressTimer);
    // 重置长按状态  
    isLongPressing = false;
    // 如果需要，可以在这里处理普通的点击事件（但要确保与双击逻辑不冲突）  
    // 注意：在这个示例中，我们不处理普通的点击事件，因为它可能与双击冲突。  
    // 如果你需要处理点击事件，请确保在 handleClick 方法中进行适当的检查。  
}
const handleLongPress = (item: appNameItem) => {
    // 在这里处理长按逻辑
    if (!isOnDrag) {
        console.log('这是一次长按')
        showCloseButton.value = !showCloseButton.value
    }
}

const delApp = (app: appNameItem) => {
    console.log('删除', app)

    dialog.warning({
        title: '删除',
        content: `确定删除 ${app.名称} ?`,
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => {
            let data = {
                "应用名称": app['缩写'], // 必填
                "应用类型": "应用", // 必填
                "数据类型": app['类型']
            }

            APP_DEL({ "params": JSON.stringify(data) }).then((res: any) => {
                if (res.stacode == 200) {
                    message.success(res.message)
                    const delItemIndex = dynamicApps.value.findIndex((item: any) => item.id === app.id);
                    if (delItemIndex !== -1) {
                        dynamicApps.value.splice(delItemIndex, 1);
                    }
                }
                else {
                    message.error(res.message)
                }
            }).catch((err: any) => {
                console.log('err', err);
            })
        }
    })
}

let isOnDrag = false
let dragFile: any
let dropFolder: any
const currentGroup = ref()
const showDropMoveOut = ref(false)
const onDragStart = (file: any) => {
    console.log('拖拽了：', file)
    dragFile = file
    isOnDrag = true
    showCloseButton.value = false

    setTimeout(() => { // 拖拽1秒后，出现新item
        if (isOnDrag && showModal.value) {
            showDropMoveOut.value = true
        }
    }, 1000);
};

const onDragEnd = (file: any) => {
    console.log('拖拽松开了：', file)
    isOnDrag = false
    showCloseButton.value = false
    showDropMoveOut.value = false
};

const onDropMoveOutOfFolder = () => {
    showDropMoveOut.value = false
    showModal.value = false
    console.log('拖拽到外面', dragFile, currentGroup.value)

    const itemToShow = dynamicApps.value.find(app => app.id === dragFile.id);
    itemToShow.hide = false

    const { id } = dragFile

    const index = currentGroup.value.appIds.findIndex((appId: string) => appId === id);
    if (index !== -1) {  // 文件夹中删除这个元素，更新文件夹中的图标组和id组
        currentGroup.value.appIds.splice(index, 1);
        currentGroup.value.图标组.splice(index, 1);
        // 后端更新
        updateGroupApps(currentGroup.value.appIds)
    }

    if (currentGroup.value.appIds.length <= 1) { // 删除文件夹
        // 前端更新
        const index = dynamicApps.value.findIndex((app: any) => app.id === currentGroup.value.id);
        dynamicApps.value.splice(index, 1);
        currentGroup.value.appIds.forEach((elementId: string) => { // 恢复所有的APP
            const itemToShow = dynamicApps.value.find(app => app.id === elementId);
            itemToShow.hide = false
        });
        // 后端更新
        dropGroup()
    }
}

const onDrop = (event: any, dropItem: any) => {
    console.log('放到了', dropItem)
    isOnDrag = false

    if (dragFile && dropItem) {
        if (dragFile.id === dropItem.id) { // 自己拖拽到自己，没效果
            return
        }
        if (dragFile.type === 'group') { // 拖拽文件夹放到任何地方，没效果
            return
        }
        if (showModal.value) { // 在文件夹内部又企图进行合并，没效果
            return
        }
        // const itemToHide = dynamicApps.value.find(app => app.id === dragFile.id);
        // itemToHide.hide = true
        if (dropItem.type === 'group') { // 拖拽目标是文件夹
            
            const groupToUpdate = dynamicApps.value.find(app => app.id === dropItem.id);
            // 前端更新
            // if (groupToUpdate.图标组.length < 4) {
            //     groupToUpdate.图标组 = [...groupToUpdate.图标组, dragFile.图标];
            // }
            // groupToUpdate.appIds = [...groupToUpdate.appIds, dragFile.id]
            // 后端更新
            updateGroupApps([...groupToUpdate.appIds, dragFile.id], dropItem.id)
        }
        else { // 拖拽目标是文件
            // 前端更新
            // const targetItemToHide = dynamicApps.value.find(app => app.id === dropItem.id);
            // targetItemToHide.hide = true
            // dynamicApps.value.push({
            //     id: dragFile.id + dropItem.id,
            //     appIds: [dragFile.id, dropItem.id],
            //     名称: '未命名分组',
            //     图标组: [dragFile.图标, dropItem.图标],
            //     type: 'group',
            // })
            // 后端更新
            createGroup([dragFile.id, dropItem.id])
        }
    }
}
const showModal = ref(false)
const showFolder = (item:any) => {
    console.log('showFolder', item)
    if(item.type === 'group') {
        showModal.value = true
        currentGroup.value = item
        console.log(currentGroup.value.appIds)
    }
}
const updateGroupApps = (appIds: string[], groupId?: string) => {
    APP_GROUP_UPD({
        "params": JSON.stringify({
            "类型": "更新",
            "内容": {
                "id": groupId || currentGroup.value.id,
                "子应用": appIds,
            }
        })
    }).then((res: any) => {
        if (res.stacode == 200) {

        }
    }).catch((err: any) => {
        console.log('err', err);
    })
}
const changeGroupName = () => {
    APP_GROUP_UPD({
        "params": JSON.stringify({
            "类型": "更新",
            "内容": {
                "id": currentGroup.value.id,
                "应用名称": currentGroup.value.名称,
            }
        })
    }).then((res: any) => {
        if (res.stacode == 200) {

        }
    }).catch((err: any) => {
        console.log('err', err);
    })
}

const createGroup = (appIdList: string[]) => {
    APP_GROUP_UPD({
        "params": JSON.stringify({
            "类型": "新建",
            "内容": {
                "应用名称": '未命名分组',
                "子应用": appIdList
            }
        })
    }).then((res: any) => {
        if (res.stacode == 200) {

        }
    }).catch((err: any) => {
        console.log('err', err);
    })
}

const dropGroup = () => {
    APP_GROUP_UPD({
        "params": JSON.stringify({
            "类型": "删除",
            "内容": {
                "id": currentGroup.value.id,
            }
        })
    }).then((res: any) => {
        if (res.stacode == 200) {

        }
    }).catch((err: any) => {
        console.log('err', err);
    })
}

</script>
<template>
    <n-modal v-model:show="showModal" preset="card" :closable="false"
        style="background-color: rgba(255, 255, 255, 0.6); border-radius: 15px; width: auto; height: auto">
        <div style="text-align: center;margin-bottom: 15px;">
            <n-input v-if="showModal" v-model:value="currentGroup.名称" size="small" round clearable placeholder="分组名"
                maxlength="8" style="width: 150px; background: none;" @change="changeGroupName"/>
        </div>
        <n-grid :x-gap="30" :y-gap="30" cols="4">
            <n-grid-item v-for="(app, index) in dynamicApps.filter((item:any) => currentGroup.appIds.includes(item.id))"
                class="girditem" @dblclick="handleClick(app)" @mousedown="handleMouseDown(app)"
                @mouseup="handleMouseUp()" @mouseleave="handleMouseUp()" @contextmenu.prevent="none">
                <n-flex vertical draggable="true" @dragstart="onDragStart(app)" @dragend="onDragEnd(app)" style="cursor: pointer;">
                    <n-badge value="x" color="lightGray" :show="showCloseButton"
                        @click="showCloseButton ? delApp(app) : undefined">
                        <div class="icon-wrapper" @click.stop="console.log('单击了应用图标')"
                            style="background-color: rgba(255, 255, 255, 0.4);">
                            <n-grid cols="2" v-if="app.图标组" style="margin: 6px">
                                <n-grid-item v-for="icon in app.图标组" style="text-align: center;">
                                    <svg-icon style="font-size: 25px;" :iconClass="icon" className="icon" />
                                </n-grid-item>
                            </n-grid>
                            <svg-icon v-else style="font-size: 60px; " :iconClass="app.图标" className="icon" />
                        </div>
                    </n-badge>
                    <n-text
                        style=" text-align: center;font-size: 15px;color:white; text-shadow: 1px 1px 0 black; /* 右下角阴影 */ font-weight:500;">
                        {{ app.名称 }}
                    </n-text>
                </n-flex>
            </n-grid-item>
            <n-grid-item v-if="showDropMoveOut">
                <n-flex vertical>
                    <div class="icon-wrapper" style="background-color: rgba(255, 255, 255, 0.2); border-radius: 100px;"
                        @dragover.prevent @drop="onDropMoveOutOfFolder">
                        <svg-icon style="font-size: 40px; opacity: 0.6;" iconClass="zhongzuo" className="icon" />
                    </div>
                    <n-text
                        style=" text-align: center;font-size: 12px;color:white; text-shadow: 1px 1px 0 black; /* 右下角阴影 */ font-weight:500;">
                        拖拽到这里<br>移出应用
                    </n-text>
                </n-flex>
            </n-grid-item>
        </n-grid>
    </n-modal>
    <n-flex class="myapp">
        <n-grid :x-gap="2" :y-gap="2" cols="15" style=" grid-auto-rows: minmax(80px, 200px); ">
            <!-- 固定的基础应用 -->
            <template v-for="(item, index) in defaultApps">
                <n-grid-item class="girditem" @dblclick="handleClick(item)" @contextmenu.prevent="none">
                    <n-flex vertical>
                        <n-button text style="font-size: 60px; ">
                            <n-icon
                                style="box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.5); background-color: rgba(255, 255, 255, 0.9); border-radius: 5px; padding: 4px; width: 72px; height: 72px;">
                                <svg-icon :iconClass="item.图标" className="icon" />
                            </n-icon>
                        </n-button>
                        <n-text
                            style=" text-align: center;font-size: 15px;color:white; text-shadow: 1px 1px 0 black; /* 右下角阴影 */ font-weight:500;">
                            {{ item.名称 }}
                        </n-text>
                    </n-flex>
                </n-grid-item>
            </template>
            <!-- 动态的应用 -->
            <template v-for="(app, index) in dynamicApps.filter((item:any) => !item.hide)">
                <n-grid-item class="girditem" @dblclick="handleClick(app)" @mousedown="handleMouseDown(app)"
                    @mouseup="handleMouseUp()" @mouseleave="handleMouseUp()" @contextmenu.prevent="none">
                    <n-flex vertical draggable="true" @dragstart="onDragStart(app)" @dragend="onDragEnd(app)" style="cursor: pointer;">
                            <n-badge value="x" color="lightGray" :show="showCloseButton"
                                @click="showCloseButton ? delApp(app) : undefined">
                                <div class="icon-wrapper" @click.stop="console.log('单击了应用图标')" @dragover.prevent
                                    @drop="onDrop($event, app)">
                                    <n-grid cols="2" v-if="app.图标组" style="margin: 6px">
                                        <n-grid-item v-for="icon in app.图标组" style="text-align: center;">
                                            <svg-icon style="font-size: 25px;" :iconClass="icon" className="icon" />
                                        </n-grid-item>
                                    </n-grid>
                                    <svg-icon v-else style="font-size: 60px;" :iconClass="app.图标" className="icon" />
                                </div>
                            </n-badge>
                        <n-text
                            style=" text-align: center;font-size: 15px;color:white; text-shadow: 1px 1px 0 black; /* 右下角阴影 */ font-weight:500;">
                            {{ app.名称 }}
                        </n-text>
                    </n-flex>
                </n-grid-item>
            </template>
        </n-grid>
    </n-flex>
</template>
<style scoped>
.icon-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.5);
    background-color: rgba(255, 255, 255, 0.3);
    border-radius: 5px;
    width: 72px;
    height: 72px;
}

.myapp {
    height: 100%;
    width: 100%;
    padding: 10px;
    /* background-color: #ffffff; */
}

.girditem {

    border: 0px solid #2e2e2e;
    display: flex;
    justify-content: center;
    align-items: center;

}
</style>